package org.example.iot;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.concurrent.TimeUnit;

/**
 * 有限振动测试
 */
public class Test0x0002 {
    public static void main(String[] args) throws InterruptedException {
            NioEventLoopGroup worker = new NioEventLoopGroup();
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.channel(NioSocketChannel.class);
            bootstrap.group(worker);
            bootstrap.option(NioChannelOption.TCP_NODELAY, true);
            bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
                @Override
                protected void initChannel(NioSocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                        //和服务器建立连接之后的回调
                        @Override
                        public void channelActive(ChannelHandlerContext ctx) throws Exception {
                            System.out.println("连接建立");
                            //执行登录
                            byte[] loginBytes = ByteBufUtil.decodeHexDump("028f525c6500990001014457475a434a59323331313038393939322e30322e30303031015b525c6538363531333730363131313638383934363030383435343337303332383338393836303443353130323232303237333238331f3c1f2c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f130d0a");
                            ctx.writeAndFlush(Unpooled.buffer().writeBytes(loginBytes));
                            TimeUnit.SECONDS.sleep(3);
                            //上报传感器信息
                            //头部
                            byte[] bytes1 = ByteBufUtil.decodeHexDump("025034dc5f");

                            ByteBuf byteBuf= ByteBufAllocator.DEFAULT.buffer();
                            byteBuf.writeBytes(bytes1);
                            //数据长度 = 指令码 + 传感器数量 + 传感器信息
                            byteBuf.writeShort(2+1+20+20+20);
                            //写入指令码
                            byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0002"));
                            //写入传感器数量
                            byteBuf.writeByte(3);
                            //写入20字节445747
                            byteBuf.writeBytes(ByteBufUtil.decodeHexDump("010101014457475a434a59323331323138313032"));
                            byteBuf.writeBytes(ByteBufUtil.decodeHexDump("010101014457475a434a59323331323138313033"));
                            byteBuf.writeBytes(ByteBufUtil.decodeHexDump("010101014457475a434a59323331323138313034"));

                            //写入CRE
                            byte[] crcBytes = crc16CCITTFalse(ByteBufUtil.getBytes(byteBuf));
                            byteBuf.writeBytes(crcBytes);
                            //写入尾部
                            byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0d0a"));
                            ctx.writeAndFlush(byteBuf);
                        }
                    });
                }
            });
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9876).sync();
            Channel channel = channelFuture.channel();

    }

    public static byte[] crc16CCITTFalse(byte[] bytes) {
        int crc = 0xffff; // initial value
        int polynomial = 0x1021; // poly value
        for (int index = 0; index < bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit){
                    crc ^= polynomial;
                }
            }
        }
        crc &= 0xffff;
        return new byte[] { (byte) ((0xff00 & crc) >> 8),(byte) (0xff & crc)  };
    }
}